/* 
 * Copyright (C) 2012 UTSChedule
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package utsc.apps.utschedule.ui.activities;

import java.util.ArrayList;
import java.util.Calendar;
import utsc.apps.utschedule.R;
import utsc.apps.utschedule.UTSCheduleApp;
import utsc.apps.utschedule.classes.Course;
import utsc.apps.utschedule.classes.Timetable;
import utsc.apps.utschedule.ui.InputDialogFragment;
import utsc.apps.utschedule.ui.InputDialogFragment.OnInputListener;
import utsc.apps.utschedule.ui.MessageDialogFragment;
import utsc.apps.utschedule.ui.MyDatePickerDialogFragment;
import utsc.apps.utschedule.ui.interfaces.OnSyncListener;
import utsc.apps.utschedule.ui.interfaces.TimetableActivity;
import utsc.apps.utschedule.util.AppUtils;
import utsc.apps.utschedule.util.GenericActionModeCallback;
import utsc.apps.utschedule.util.TimetableHelper;
import utsc.apps.utschedule.util.Validator;
import utsc.apps.utschedule.util.database.DatabaseManager;
import utsc.apps.utschedule.widget.ButtonsLayout;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;

import android.app.Activity;
import android.app.DatePickerDialog.OnDateSetListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;

/**
 * The form to create/update a {@link Timetable timetable} entry. It also allows
 * user to sync his/her course timetables from Intranet.
 * 
 */
public class TimetableFormActivity extends GenericFormActivity<Timetable> implements GenericActionModeCallback.OnMenuItemClickedListener,TimetableActivity,OnDateSetListener,OnInputListener,OnSyncListener<Course>{

	public static final String TAG="TimetableFormActivity";
	private EditText _txtTimetableTitle;
	private EditText _txtYear;
	private EditText _txtStartDate;
	private Spinner _spinnerSession;
	private LinearLayout _emptyCourseLayout;
	private Button _btnAddCourse;
	private ButtonsLayout _courseBtnsLayout;
	private ArrayList<Object> _courses;
	private Timetable _timetable;
	private Validator _validator;
	private boolean _isFirstSync=false;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		Intent requestIntent=getIntent();
		_requestCode=requestIntent.getIntExtra("RequestCode", -1);
		
		setupBasicResources();
		
		switch (_requestCode) {
			case TimetableActivity.RESULT_NEW_TIMETABLE:
				getSupportActionBar().setTitle("Add Timetable");
				setupResourcesForNew(requestIntent);
				_btnAddCourse.setOnClickListener(this);
				_validator=Validator.newInstance(TAG);
				//ask the user if they want to sync the courses from intranet
				showDialogFragment(InputDialogFragment.newInstance("Sync Courses", "Do you want to sync your courses from Intranet?", "Ok",null), InputDialogFragment.TAG);
				break;
				
			default:
				break;
		}
	}
	
	@Override
	public void onClick(View v) {
		int id=v.getId();
		if (id==R.id.btn_add_new_course) {
				Intent courseForm = new Intent(this, CourseFormActivity.class);
				startActivityForResult(courseForm, RESULT_NEW_COURSE);
		}else if (id==R.id.frm_txt_timetable_startdate) {
			String startdate=_txtStartDate.getText().toString();
			Calendar c=TimetableHelper.convertFromDateTimeString(startdate, TimetableHelper.TYPE_DATE);
			int year=c.get(Calendar.YEAR);
			int month=c.get(Calendar.MONTH);
			int day=c.get(Calendar.DAY_OF_MONTH);
			showDialogFragment(MyDatePickerDialogFragment.newInstance(this, year, month, day), MyDatePickerDialogFragment.TAG);
		}
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getSupportMenuInflater().inflate(R.menu.add_cancel_menu, menu);
		//add the sync menu item manually
		menu.add(Menu.CATEGORY_SECONDARY, R.id.sync, 100, R.string.lb_sync).setIcon(R.drawable.ic_action_refresh);
		return true;
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		UTSCheduleApp app=(UTSCheduleApp) getApplication();
		Timetable t=app.get_currentActiveTimetable();
		if (t!=null) {
			final ArrayList<Object> courses=new ArrayList<Object>();
			ArrayList<Course> savedCourses = null;
				savedCourses = t.get_courseList();
			for (Course course : savedCourses) {
				courses.add(course);
			}
			if (courses!=null) {
				_courseBtnsLayout.set_items(courses);
			}
			
		}else {
			//check whether or not we got the courses from the sync 
			if (_isFirstSync) {
				//retrieve the cache from the main application
				_courses=new ArrayList<Object>(app.get_syncedCourses());
				//clear off teh cache from the main application
				app.set_syncedCourses(null);
				_isFirstSync=false;
			}
			//reset the courses to the course section
			if (_courses!=null&& !_courses.isEmpty()) {
				_courseBtnsLayout.set_items(_courses);
			}
		}
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		
		if (resultCode==Activity.RESULT_OK) {
			//Toast.makeText(this, "got result from "+CourseFormActivity.class.toString(), Toast.LENGTH_SHORT).show();
			if (requestCode==TimetableActivity.RESULT_SYNC_COURSE) {
				_isFirstSync=true;
			}else {
				Course c=new Course(data);
				final Object d=getLastCustomNonConfigurationInstance();
				if (d!=null) {
					//Bundle savedData=(Bundle)d;
					final ArrayList<Object> savedList=(ArrayList<Object>)d;//(ArrayList<Object>) savedData.getSerializable(SAVED_COURSES_KEY);
					_courseBtnsLayout.set_items(savedList);
				}
				_courseBtnsLayout.add_item(c);
			}
			
			_emptyCourseLayout.setVisibility(View.GONE);
			_courseBtnsLayout.setVisibility(View.VISIBLE);
		}
	}
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		onMenuItemClicked(item);
		return true;
	}
		
	@Override
	public Object onRetainCustomNonConfigurationInstance() {
		return _courseBtnsLayout.get_items();
	}
	
	@Override
	public void startActivityForResult(Intent intent, int requestCode) {
		intent.putExtra("RequestCode", requestCode);
		intent.putExtra("RequestResult", true);
		// we should always call the actual startActivityForResult method from the parent 
		super.startActivityForResult(intent, requestCode);
	}
	
	@Override
	protected void setupBasicResources() {
		setContentView(R.layout.activity_timetable_form);
		_txtTimetableTitle=(EditText) findViewById(R.id.frm_txt_timetabletitle);
		_spinnerSession=(Spinner) findViewById(R.id.frm_spinner_session);
		_txtYear=(EditText) findViewById(R.id.frm_txt_timetable_year);
		_emptyCourseLayout=(LinearLayout) findViewById(R.id.empty_course_layout);
		_btnAddCourse=(Button) findViewById(R.id.btn_add_new_course);
		_courseBtnsLayout=(ButtonsLayout) findViewById(R.id.courses_btns_layout);
		_courseBtnsLayout.set_onAddNewButtonClickListener(this);
		_courses=new ArrayList<Object>();
		_txtStartDate=(EditText) findViewById(R.id.frm_txt_timetable_startdate);
		_txtStartDate.setOnClickListener(this);
		final Object data=getLastCustomNonConfigurationInstance();
		if (data!=null) {
			_courses=(ArrayList<Object>) data;//savedData.getSerializable(SAVED_COURSES_KEY);
			_emptyCourseLayout.setVisibility(View.GONE);
			_courseBtnsLayout.setVisibility(View.VISIBLE);
		}
		
	}

	@Override
	protected void setupResourcesForNew(Intent requestIntent) {
		int year=TimetableHelper.getCurrentDateCalendar().get(Calendar.YEAR);
		_txtYear.setText(year+"");
		_spinnerSession.setSelection(TimetableHelper.getSession());
		
		String defaultTitle=_spinnerSession.getSelectedItem().toString()+" "+year;
		
		_txtTimetableTitle.setText(defaultTitle);
		_txtStartDate.setText(TimetableHelper.getFormattedString(System.currentTimeMillis(), TimetableHelper.TYPE_DATE));
		
	}
	
	
	
	@Override
	public void onMenuItemClicked(MenuItem item) {
		int itemId=item.getItemId();
		if (itemId!=R.id.cancel&&itemId!=android.R.id.home&&itemId!=R.id.sync) {
			Intent resultIntent=new Intent();
			switch (_requestCode) {
			case TimetableActivity.RESULT_NEW_TIMETABLE:
				_timetable=new Timetable();
				_timetable.set_title(_txtTimetableTitle.getText().toString());
				_timetable.set_year(Integer.parseInt(_txtYear.getText().toString()));
				_timetable.set_session((String) _spinnerSession.getSelectedItem());
				_timetable.set_startdate(TimetableHelper.convertFromDateTimeString(_txtStartDate.getText().toString(), TimetableHelper.TYPE_DATE).getTimeInMillis());
				
				//form validation
				if (validate(_timetable)) {
					ArrayList<Object> courses=_courseBtnsLayout.get_items();
					_timetable.set_courses(DatabaseManager.getInstance(getApplicationContext()).getEmptyCourseCollection());
					//first save the new timetable entry
					DatabaseManager.getInstance(getApplicationContext()).saveTimetable(_timetable);
					
					//reset the start/end hour preferences
					SharedPreferences sharedPreferences=PreferenceManager.getDefaultSharedPreferences(this);
					sharedPreferences.edit().remove("start_hour").commit();
					sharedPreferences.edit().remove("end_hour").commit();
					
					//check whether or not we have a list courses to save
					if (courses!=null) {
						ArrayList<Course> coursesList=new ArrayList<Course>();
						for (Object object : courses) {
							Course c=(Course)object;
							c.set_timetable(_timetable);
							coursesList.add(c);
						}
						//perform the batch save for the courses
						DatabaseManager.getInstance(this).saveCourses(_timetable.get_timetableID(), coursesList);
					}
					//set the current active timetable to this timetable entry
					UTSCheduleApp app=(UTSCheduleApp) getApplication();
					DatabaseManager.getInstance(getApplicationContext()).refreshTimetable(_timetable);
					//refresh the course list as well
					_timetable.refreshCourseList();
					app.setActiveTimetable(_timetable);
				}else {
					showDialogFragment(MessageDialogFragment.newInstance(AppUtils.ERROR_TITLE_TIMETABLE_ADD, _validator.get_errorMessages()), MessageDialogFragment.TAG);
					return;
				}
				break;
			default:
				break;
			}
			setResult(Activity.RESULT_OK, resultIntent);
			finish();
			
		}else {
			if (itemId==R.id.sync) {
				syncCourses();
			}else {
				setResult(Activity.RESULT_CANCELED);
				finish();
			}
			
		}		
	}

	@Override
	protected boolean validate(Timetable object) {
		_validator.reset();
		_validator.checkNull(object.get_title(), AppUtils.ERROR_MESSAGE_TIMETABLE_TITLE);
		_validator.checkNull(object.get_year()+"", AppUtils.ERROR_MESSAGE_TIMETABLE_YEAR);
		_validator.checkNull(object.get_startdate()+"", AppUtils.ERROR_MESSAGE_TIMETABLE_STARTDATE);
		if (_validator.get_errorMessages()==null) {
			return true;
		}
		return false;
	}

	@Override
	public void onDateSet(DatePicker view, int year, int monthOfYear,
			int dayOfMonth) {
		Calendar c=TimetableHelper.getCurrentDateCalendar();
		c.set(year, monthOfYear, dayOfMonth);
		_txtStartDate.setText(TimetableHelper.getFormattedString(c.getTimeInMillis(), TimetableHelper.TYPE_DATE));
	}

	@Override
	protected void setupResourcesForUpdate(Intent requestIntent) {}
	
	/**
	 * A wrapper method to perform the sync course action.
	 */
	private void syncCourses() {
		//check whether or not we have the login preference
		if (AppUtils.hasLoginPreferences(this)) {
			//if yes, run the task 
			new SyncCourseTask(this, TimetableHelper.getCurrentTermString()).execute(AppUtils.getLoginPreferences(this));
		}else {
			//otherwise, start the logic activity
			Intent syncIntent=new Intent(this,LoginActivity.class);
			startActivityForResult(syncIntent,TimetableActivity.RESULT_SYNC_COURSE);
		}
	}

	@Override
	public void setupInputs(View v) {}

	@Override
	public void onInputSaveListener(View v) {
		syncCourses();
	}

	@Override
	public void onSyncCompleted(ArrayList<Course> result) {
		if (result!=null&& !result.isEmpty()) {
			_courses=new ArrayList<Object>(result);
			_courseBtnsLayout.set_items(_courses);
			_courseBtnsLayout.invalidate();
			_emptyCourseLayout.setVisibility(View.GONE);
			_courseBtnsLayout.setVisibility(View.VISIBLE);
		}
	}
}
